package windbell.domain.risk.impl;

import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import java.util.Collection;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;
import windbell.domain.risk.RiskCheck;
import windbell.domain.risk.RiskCheckSource;
import windbell.domain.risk.RiskCheckSourceStatus;
import windbell.domain.risk.RiskCheckSourceType;
import windbell.domain.risk.RiskCheckTarget;
import windbell.domain.risk.RiskCheckTemplate;
import windbell.domain.risk.RiskCheckTemplateItem;
import windbell.domain.risk.impl.RiskCheckImpl;
import windbell.domain.risk.impl.RiskCheckTemplateImpl;
import windbell.domain.risk.proxy.RiskCheckSourceProxy;

@Entity
@DiscriminatorValue("RISKCHECKSOURCE_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "riskchecksource")
public abstract class RiskCheckSourceImpl extends BaseModelObject implements RiskCheckSource {
  public RiskCheckSourceImpl() {
    super();
  }
  
  public RiskCheckSourceImpl(final RiskCheckTemplate checkTemplate) {
    super();
    this.checkTemplate = checkTemplate;
  }
  
  private RiskCheckSourceStatus Status;
  
  public RiskCheckSourceStatus getStatus() {
    return this.Status;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start() {
    
    Status=RiskCheckSourceStatus.created;
  }
  
  public void start() {
    if(Status==null){
    	_start();
    	getModelObjectLogService().createLog(this,"Status","Start");
    	getBeanFactory().getBean(windbell.domain.risk.events.RiskCheckSourceEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private RiskCheck _createRiskCheck(final Procedure1<? super RiskCheck> init) {
    RiskCheck riskCheck=RiskCheckImpl.create(getObjectFactory());
    
    final Procedure1<RiskCheck> _function = new Procedure1<RiskCheck>() {
        public void apply(final RiskCheck it) {
          it.setSource(RiskCheckSourceImpl.this);
          init.apply(it);
          it.checkValid();
          it.createItemsFromTemplate(RiskCheckSourceImpl.this.checkTemplate);
        }
      };
    RiskCheck _doubleArrow = ObjectExtensions.<RiskCheck>operator_doubleArrow(riskCheck, _function);
    return _doubleArrow;
  }
  
  public RiskCheck createRiskCheck(final Procedure1<? super RiskCheck> init) {
    if(Status==RiskCheckSourceStatus.created){
    	RiskCheck result = _createRiskCheck(init);
    	getModelObjectLogService().createLog(this,"Status","createRiskCheck");
    	getBeanFactory().getBean(windbell.domain.risk.events.RiskCheckSourceEventsManager.class).fireCreateRiskCheck(this,init);
    	return result;
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("Status.name()");
    }
  }
  
  private void _delete() {
    
    Iterable<RiskCheck> _riskChecks = this.getRiskChecks();
    final Procedure1<RiskCheck> _function = new Procedure1<RiskCheck>() {
        public void apply(final RiskCheck it) {getObjectFactory().delete(it);
          
        }
      };
    IterableExtensions.<RiskCheck>forEach(_riskChecks, _function);getObjectFactory().delete(this);
    
  }
  
  public void delete() {
    if(Status==RiskCheckSourceStatus.created){
    	_delete();
    	getModelObjectLogService().createLog(this,"Status","delete");
    	getBeanFactory().getBean(windbell.domain.risk.events.RiskCheckSourceEventsManager.class).fireDelete(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  public Boolean isCreated() {
    return windbell.domain.risk.RiskCheckSourceStatus.created==Status;
  }
  
  private RiskCheckSourceType type;
  
  public RiskCheckSourceType getType() {
    return this.type;
  }
  
  public RiskCheckSource setType(final RiskCheckSourceType type) {
    this.type = type;
    return this;			
    
  }
  
  private Date date;
  
  public Date getDate() {
    return this.date;
  }
  
  public RiskCheckSource setDate(final Date date) {
    this.date = date;
    return this;			
    
  }
  
  private String description;
  
  public String getDescription() {
    return this.description;
  }
  
  public RiskCheckSource setDescription(final String description) {
    this.description = description;
    return this;			
    
  }
  
  @JoinColumn(name = "checkTemplate_id")
  @ManyToOne(targetEntity = RiskCheckTemplateImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RiskCheckTemplate checkTemplate;
  
  public RiskCheckTemplate getCheckTemplate() {
    return this.checkTemplate;
  }
  
  public RiskCheckSource setCheckTemplate(final RiskCheckTemplate checkTemplate) {
    this.checkTemplate = checkTemplate;
    return this;			
    
  }
  
  public Iterable<RiskCheck> getRiskChecks() {
    IGenericQuery<RiskCheck> query=getObjectFactory().createGenericQuery(RiskCheck.class,"select e from windbell.domain.risk.impl.RiskCheckImpl as e   where ((e.source) = (:this)) and  e.active = 1      ").setParameter("this",this);
    Collection<RiskCheck> _list = query.list();
    return _list;
  }
  
  public Iterable<RiskCheckTarget> getCheckTargets() {
    IGenericQuery<RiskCheckTarget> query=getObjectFactory().createGenericQuery(RiskCheckTarget.class,"select  distinct c from windbell.domain.risk.impl.RiskCheckImpl as e left join  e.checkTarget as c   where ((e.source) = (:this)) and  e.active = 1      ").setParameter("this",this);
    Collection<RiskCheckTarget> _list = query.list();
    return _list;
  }
  
  public Collection<RiskCheckTemplateItem> getRiskCheckTemplateItems() {
    Collection<RiskCheckTemplateItem> _checkList = this.checkTemplate.getCheckList();
    return _checkList;
  }
  
  public Boolean getRiskCheckStatus() {
    Iterable<RiskCheck> _riskChecks = this.getRiskChecks();
    final Function1<RiskCheck,Boolean> _function = new Function1<RiskCheck,Boolean>() {
        public Boolean apply(final RiskCheck it) {
          Boolean _isFinished = it.isFinished();
          boolean _not = (!_isFinished);
          return Boolean.valueOf(_not);
        }
      };
    boolean _exists = IterableExtensions.<RiskCheck>exists(_riskChecks, _function);
    return Boolean.valueOf(_exists);
  }
  
  public RiskCheckSourceProxy toProxy() {
    windbell.domain.risk.proxy.RiskCheckSourceProxy proxy = new windbell.domain.risk.proxy.RiskCheckSourceProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setStatus(this.getStatus().name());
    return proxy;
    
  }
}
